<!DOCTYPE html>
<html>
<head>
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <meta charset="utf-8"/>
    <title>点选图片验证码</title>
</head>

<style type="text/css">
    html{
        width: 100%;
        height: 100%;
        background-color: #16202f;
    }
    body{
        width: 100%;
        height: 100%;
        margin:0;
        padding:0;
        position: relative;
        overflow: hidden;
        font-family: "Arial", "Microsoft YaHei", "黑体", "宋体", sans-serif;
    }

    .wg-cap-root{
        width: 100%;
        height: 100%;
        display:-webkit-box;
        display:-webkit-flex;
        display:-ms-flexbox;
        display:flex;
        flex-direction: column;
        -webkit-box-align:center;
        -webkit-align-items:center;
        -ms-flex-align:center;
        align-items: center;
    }
    .wg-cap-container{
        position: relative;
        width: 330px;
        padding: 440px 15px 0 15px;
        height: 50px;
        margin: auto;
    }
    .wg-cap-container.wg-cap-dialog__active  .wg-cap-dialog {
        display: block;
    }

    @keyframes tinUpIn {
        0% { opacity:0; transform:scale(1) translateY(-500%); }
        /*50% { opacity:1; transform:scale(1.1) translateY(0); }*/
        /*70% { opacity:1; transform:scale(1.1) translateY(0); }*/
        /*90% { opacity:1; transform:scale(1.1) translateY(0);  }*/
        60% { opacity:1; transform:scale(1) translateY(0);  }
        80% { opacity:1; transform:scale(1) translateY(0); }
        100% { opacity:1; transform:scale(1) translateY(0); }
    }
    @-webkit-keyframes tinUpIn {
        0% { opacity:0; transform:scale(1) translateY(-500%); }
        /*50% { opacity:1; transform:scale(1.1) translateY(0); }*/
        /*70% { opacity:1; transform:scale(1.1) translateY(0); }*/
        /*90% { opacity:1; transform:scale(1.1) translateY(0);  }*/
        60% { opacity:1; transform:scale(1) translateY(0);  }
        80% { opacity:1; transform:scale(1) translateY(0); }
        100% { opacity:1; transform:scale(1) translateY(0); }
    }
    .wg-cap-container.wg-cap-dialog__active  .wg-cap-wrap{
        display: block;
        animation: tinUpIn 1s linear;
        -moz-animation: tinUpIn 1s linear;
        -webkit-animation: tinUpIn 1s linear;
    }
    .wg-cap-container .wg-cap-block{
        /*padding-top: 440px;*/
    }

    .wg-cap-dialog{
        position: fixed;
        z-index: 2000;
        top: 0;
        right: 0;
        bottom: 0;
        left: 0;
        display: none;
    }

    .wg-cap-wrap{
        position: absolute;
        bottom: -10px;
        z-index: 2001;
        display: none;

        padding: 15px;
        border: 1px solid rgba(206, 223, 254, 0.5);
        background: #ffffff;

        -webkit-border-radius: 10px;
        -moz-border-radius: 10px;
        border-radius: 10px;

        box-shadow: 0 0 20px rgba(100, 100, 100, 0.1);
        -webkit-box-shadow: 0 0 20px rgba(100, 100, 100, 0.1);
        -moz-box-shadow: 0 0 20px rgba(100, 100, 100, 0.1);

        -webkit-touch-callout: none;
        -webkit-user-select: none;
        -moz-user-select: none;
        -ms-user-select: none;
        user-select: none;
    }
    .wg-cap-wrap__header{
        height: 50px;
        width: 100%;
        font-size: 15px;

        display:-webkit-box;
        display:-webkit-flex;
        display:-ms-flexbox;
        display:flex;
        -webkit-box-align:center;
        -webkit-align-items:center;
        -ms-flex-align:center;
        align-items: center;
    }
    .wg-cap-wrap__header span{
        padding-right: 5px;
    }
    .wg-cap-wrap__header span em{
        padding: 0 3px;
        font-weight: bold;
        color: #3e7cff;
        font-style: normal;
    }
    .wg-cap-wrap__header .wg-cap-wrap__image{
        -webkit-border-radius: 5px;
        -moz-border-radius: 5px;
        border-radius: 5px;
        overflow: hidden;
        text-align: center;
        line-height: 1;
    }
    .wg-cap-wrap__header .wg-cap-wrap__thumb.wg-cap-wrap__hidden{
        display: none;
    }

    .wg-cap-wrap__body{
        position: relative;
        width: 300px;
        height: 240px;
        display: -webkit-box;
        display: -moz-box;
        display: -ms-flexbox;
        display: -webkit-flex;
        display: flex;
        background: #34383e;
        margin: auto;
        -webkit-border-radius: 5px;
        -moz-border-radius: 5px;
        border-radius: 5px;
        overflow: hidden;
    }
    .wg-cap-wrap__body .wg-cap-wrap__picture{
        position: relative;
        z-index: 10;
        width: 100%;
        /*height: 240px;*/
        /*max-width: 100%;*/
        /*max-height: 100%;*/
        /*object-fit: cover;*/
        /*line-height: 240px;*/
        /*text-align: center;*/
    }
    .wg-cap-wrap__body .wg-cap-wrap__picture.wg-cap-wrap__hidden{
        display: none;
    }
    .wg-cap-wrap__body .wg-cap-wrap__loading{
        position: absolute;
        z-index: 9;
        top: 50%;
        left: 50%;
        width: 68px;
        height: 68px;
        margin-left: -34px;
        margin-top: -34px;
        line-height: 68px;
        text-align: center;
    }
    .wg-cap-wrap__body .wg-cap-wrap__dot{
        position: absolute;
        z-index: 10;
        width: 22px;
        height: 22px;
        color: #cedffe;
        background: #3e7cff;
        border: 2px solid #f7f9fb;
        line-height: 20px;
        text-align: center;
        -webkit-border-radius: 22px;
        -moz-border-radius: 22px;
        border-radius: 22px;
        cursor: default;
    }

    .wg-cap-wrap__footer {
        width: 100%;
        height: 40px;
        color: #34383e;
        display:-webkit-box;
        display:-webkit-flex;
        display:-ms-flexbox;
        display:flex;
        -webkit-box-align:center;
        -webkit-align-items:center;
        -ms-flex-align:center;
        align-items: center;
        padding-top: 15px;
    }
    .wg-cap-wrap__footer .wg-cap-wrap__ico{
        flex: 1;
    }
    .wg-cap-wrap__footer .wg-cap-wrap__ico img{
        width: 24px;
        height: 24px;
        color: #34383e;
        margin: 0 5px;
        cursor: pointer;
    }
    .wg-cap-wrap__footer .wg-cap-wrap__btn{
        width: 120px;
        height: 40px;
    }
    .wg-cap-wrap__footer .wg-cap-wrap__btn button{
        width: 100%;
        height: 40px;
        letter-spacing: 2px;
        text-align: center;
        padding: 9px 15px;
        font-size: 15px;
        -webkit-border-radius: 5px;
        -moz-border-radius: 5px;
        border-radius: 5px;
        display: inline-block;
        line-height: 1;
        white-space: nowrap;
        cursor: pointer;
        color: #fff;
        background-color: #409eff;
        border: 1px solid #409eff;
        -webkit-appearance: none;
        box-sizing: border-box;
        outline: none;
        margin: 0;
        transition: .1s;
        font-weight: 500;
        -moz-user-select: none;
        -webkit-user-select: none;
    }
    .wg-cap-wrap__footer .wg-cap-wrap__btn button:hover {
        background: #66b1ff;
        border-color: #66b1ff;
        color: #fff;
    }

    .wg-cap-btn {
        width: 100%;
        height: 48px;
    }
    .wg-cap-btn .wg-cap-btn__inner{
        width: 100%;
        height: 48px;
        position: relative;
        letter-spacing: 1px;
    }
    .wg-cap-btn .wg-cap-state__default, .wg-cap-btn .wg-cap-state__error, .wg-cap-btn .wg-cap-state__success, .wg-cap-btn .wg-cap-state__over{
        position: absolute;
        width: 100%;
        height: 48px;
        font-size: 13px;
        -webkit-border-radius: 5px;
        -moz-border-radius: 5px;
        border-radius: 5px;
        display: inline-block;
        line-height: 1;
        white-space: nowrap;
        cursor: pointer;
        -webkit-appearance: none;
        box-sizing: border-box;
        outline: none;
        margin: 0;
        transition: .1s;
        font-weight: 500;
        -moz-user-select: none;
        -webkit-user-select: none;

        display:-webkit-box;
        display:-webkit-flex;
        display:-ms-flexbox;
        display:flex;
        -webkit-box-align:center;
        -webkit-align-items:center;
        -ms-flex-align:center;
        align-items: center;
        justify-content: center;
        justify-items: center;

        visibility: hidden;
    }
    .wg-cap-btn .wg-cap-state__default{
        color: #3e7cff;
        border: 1px solid #50a1ff;
        background: #ecf5ff;
        box-shadow: 0 0 20px rgba(62, 124, 255, 0.1);
        -webkit-box-shadow: 0 0 20px rgba(62, 124, 255, 0.1);
        -moz-box-shadow: 0 0 20px rgba(62, 124, 255, 0.1);
    }
    .wg-cap-btn .wg-cap-state__error{
        color: #ed4630;
        background: #fef0f0;
        border: 1px solid #ff5a34;
    }
    .wg-cap-btn .wg-cap-state__over{
        color: #ffa000;
        background: #fdf6ec;
        border: 1px solid #ffbe09;
    }
    .wg-cap-btn .wg-cap-state__success{
        color: #5eaa2f;
        background: #f0f9eb;
        border: 1px solid #8bc640;
        pointer-events: none;
    }
    .wg-cap-btn .wg-cap-active__default .wg-cap-state__default, .wg-cap-btn .wg-cap-active__error .wg-cap-state__error,.wg-cap-btn .wg-cap-active__over .wg-cap-state__over ,.wg-cap-btn .wg-cap-active__success .wg-cap-state__success {
        visibility: visible;
    }
    .wg-cap-btn .wg-cap-state__inner{
        display:-webkit-box;
        display:-webkit-flex;
        display:-ms-flexbox;
        display:flex;
        -webkit-box-align:center;
        -webkit-align-items:center;
        -ms-flex-align:center;
        align-items: center;
        justify-content: center;
        justify-items: center;
    }
    .wg-cap-btn .wg-cap-state__inner em{
        padding-left: 5px;
        color: #3e7cff;
        font-style: normal;
    }
    .wg-cap-btn .wg-cap-btn__inner .wg-cap-btn__ico{
        position: relative;
        width: 24px;
        height: 24px;
        margin-right: 12px;
        font-size: 14px;
        display: inline-block;
        float: left;
        flex: 0;
    }
    .wg-cap-btn .wg-cap-btn__inner .wg-cap-btn__ico img{
        width: 24px;
        height: 24px;
        float: left;
        position: relative;
        z-index: 10;
    }
    @keyframes ripple {
        0% { opacity: 0; }
        5% { opacity: 0.05; }
        20% { opacity: 0.35; }
        65% { opacity: 0.01;  }
        100% {
            transform: scaleX(2) scaleY(2);
            opacity: 0;
        }
    }
    @-webkit-keyframes ripple {
        0% { opacity: 0; }
        5% { opacity: 0.05; }
        20% { opacity: 0.35; }
        65% { opacity: 0.01;  }
        100% {
            transform: scaleX(2) scaleY(2);
            opacity: 0;
        }
    }
    .wg-cap-btn .wg-cap-btn__inner .wg-cap-btn__verify::after {
        background: #409eff;
        -webkit-border-radius: 50px;
        -moz-border-radius: 50px;
        border-radius: 50px;
        content: "";
        display: block;
        width: 24px;
        height: 24px;
        opacity: 0;
        position: absolute;
        top: 0;
        left: 0;
        z-index: 9;

        animation: ripple 1.3s infinite;
        -moz-animation: ripple 1.3s infinite;
        -webkit-animation: ripple 1.3s infinite;
        animation-delay: 2s;
        -moz-animation-delay: 2s;
        -webkit-animation-delay: 2s;
    }

    .wg-cap-tip{
        padding: 50px 20px 100px;
        font-size: 13px;
        color: #76839b;
        text-align: center;
        line-height: 180%;
        width: 100%;
        max-width: 680px;
    }

    .wg-cap-tip a{
        display: inline-block;
        margin: 0 5px;
    }

    .wg-cap-tip a img{
        height: 28px;
    }
</style>

<body>
<div class="wg-cap-root">
    <div id="wg-cap-container" class="wg-cap-container">
        <div class="wg-cap-block">
            <!-- wrap -->
            <div id="wg-cap-wrap" class="wg-cap-wrap">
                <div class="wg-cap-wrap__header">
                    <span>请在下图<em>依次</em>点击：</span>
                    <img id="wg-cap-thumb" class="wg-cap-wrap__thumb" src="" alt="...">
                </div>
                <div class="wg-cap-wrap__body" id="wg-cap-wrap" >
                    <img id="wg-cap-image" class="wg-cap-wrap__picture" src="" alt="...">
                    <img class="wg-cap-wrap__loading" src="" alt="正在加载中...">
                    <div id="wg-cap-dots">
                        <!-- <div class="wg-cap-wrap__dot"><span>1</span></div> -->
                    </div>
                </div>
                <div class="wg-cap-wrap__footer">
                    <div class="wg-cap-wrap__ico">
                        <img id="wg-cap-close-btn" src="" alt="关闭">
                        <img id="wg-cap-refresh-btn" src="" alt="刷新">
                    </div>
                    <div class="wg-cap-wrap__btn">
                        <button id="wg-cap-check-btn">确认</button>
                    </div>
                </div>
            </div>
            <!-- dialog -->
            <div id="wg-cap-dialog" class="wg-cap-dialog"></div>
            <!-- button -->
            <div class="wg-cap-btn">
                <!-- wg-cap-active__default wg-cap-active__error wg-cap-active__over wg-cap-active__success--->
                <div id="wg-cap-btn-control" class="wg-cap-btn__inner wg-cap-active__default">
                    <div id="wg-cap-btn-default" class="wg-cap-state__default">
                        <!-- 初始状态 -->
                        <div class="wg-cap-state__inner">
                            <div class="wg-cap-btn__ico wg-cap-btn__verify">
                                <img src="">
                            </div>
                            <span class="wg-cap-btn__text">点击按键进行验证</span>
                        </div>
                    </div>
                    <div id="wg-cap-btn-error" class="wg-cap-state__error">
                        <!-- 验证失败状态 -->
                        <div class="wg-cap-state__inner">
                            <div class="wg-cap-btn__ico">
                                <img src="" alt="失败">
                            </div>
                            <span>验证失败 <em>点击重试</em></span>
                        </div>
                    </div>
                    <div id="wg-cap-btn-over" class="wg-cap-state__over">
                        <!-- 验证次数过多状态 -->
                        <div class="wg-cap-state__inner">
                            <div class="wg-cap-btn__ico">
                                <img src="" alt="失败">
                            </div>
                            <span>点击次数过多 <em>点击重试</em></span>
                        </div>
                    </div>
                    <div class="wg-cap-state__success">
                        <!-- 验证成功状态 -->
                        <div class="wg-cap-state__inner">
                            <div class="wg-cap-btn__ico">
                                <img src="" alt="成功">
                            </div>
                            <span>已验证成功</span>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
    <!-- tip -->
    <div class="wg-cap-tip">
        <a target="_blank" href="https://github.com/wenlng/go-captcha/releases"><img src="https://img.shields.io/github/tag/wenlng/go-captcha.svg" alt="version"></a>
        <!-- Github Button -->
        <script type="text/javascript">
            /*!
         * github-buttons v2.21.1
         * (c) 2021 なつき
         * @license BSD-2-Clause
         */
            !function(){"use strict";var e=window.document,o=e.location,t=window.Math,r=window.HTMLElement,a=window.XMLHttpRequest,n="github-button",i="https://buttons.github.io/buttons.html",c="github.com",l=a&&"prototype"in a&&"withCredentials"in a.prototype,d=l&&r&&"attachShadow"in r.prototype&&!("prototype"in r.prototype.attachShadow),s=function(e,o){for(var t=0,r=e.length;t<r;t++)o(e[t])},u=function(e){return function(o,t,r){var a=e.createElement(o);if(null!=t)for(var n in t){var i=t[n];null!=i&&(null!=a[n]?a[n]=i:a.setAttribute(n,i))}return null!=r&&s(r,(function(o){a.appendChild("string"==typeof o?e.createTextNode(o):o)})),a}},h=u(e),g=function(e){var o;return function(){o||(o=1,e.apply(this,arguments))}},f=function(e,o){return{}.hasOwnProperty.call(e,o)},b=function(e){return(""+e).toLowerCase()},p=function(e,o,t,r){null==o&&(o="&"),null==t&&(t="="),null==r&&(r=window.decodeURIComponent);var a={};return s(e.split(o),(function(e){if(""!==e){var o=e.split(t);a[r(o[0])]=null!=o[1]?r(o.slice(1).join(t)):void 0}})),a},m=function(e,o,t){e.addEventListener?e.addEventListener(o,t,!1):e.attachEvent("on"+o,t)},v=function(e,o,t){e.removeEventListener?e.removeEventListener(o,t,!1):e.detachEvent("on"+o,t)},w=function(e,o,t){var r=function(){return v(e,o,r),t.apply(this,arguments)};m(e,o,r)},k=function(e,o,t){if(null!=e.readyState){var r="readystatechange",a=function(){if(o.test(e.readyState))return v(e,r,a),t.apply(this,arguments)};m(e,r,a)}},x={light:".btn{color:#24292f;background-color:#ebf0f4;border-color:#ccd1d5;border-color:rgba(27,31,36,.15);background-image:url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'%3e%3clinearGradient id='o' x2='0' y2='1'%3e%3cstop stop-color='%23f6f8fa'/%3e%3cstop offset='90%25' stop-color='%23ebf0f4'/%3e%3c/linearGradient%3e%3crect width='100%25' height='100%25' fill='url(%23o)'/%3e%3c/svg%3e\");background-image:-moz-linear-gradient(top, #f6f8fa, #ebf0f4 90%);background-image:linear-gradient(180deg, #f6f8fa, #ebf0f4 90%);filter:progid:DXImageTransform.Microsoft.Gradient(startColorstr='#FFF6F8FA', endColorstr='#FFEAEFF3')}:root .btn{filter:none}.btn:focus,.btn:hover{background-color:#e9ebef;background-position:0 -0.5em;border-color:#caccd1;border-color:rgba(27,31,36,.15);background-image:url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'%3e%3clinearGradient id='o' x2='0' y2='1'%3e%3cstop stop-color='%23f3f4f6'/%3e%3cstop offset='90%25' stop-color='%23e9ebef'/%3e%3c/linearGradient%3e%3crect width='100%25' height='100%25' fill='url(%23o)'/%3e%3c/svg%3e\");background-image:-moz-linear-gradient(top, #f3f4f6, #e9ebef 90%);background-image:linear-gradient(180deg, #f3f4f6, #e9ebef 90%);filter:progid:DXImageTransform.Microsoft.Gradient(startColorstr='#FFF3F4F6', endColorstr='#FFE8EAEE')}:root .btn:focus,:root .btn:hover{filter:none}.btn:active{background-color:#e5e9ed;border-color:#c7cbcf;border-color:rgba(27,31,36,.15);box-shadow:inset 0 .15em .3em rgba(27,31,36,.15);background-image:none;filter:none}.social-count{color:#24292f;background-color:#fff;border-color:#ddddde;border-color:rgba(27,31,36,.15)}.social-count:focus,.social-count:hover{color:#0969da}.octicon-heart{color:#bf3989}",light_high_contrast:".btn{color:#0e1116;background-color:#e7ecf0;border-color:#2f3237;border-color:rgba(1,4,9,.8);background-image:none;filter:none}.btn:focus,.btn:hover{background-color:#c4cdd5;background-position:0 -0.5em;border-color:#282c32;border-color:rgba(1,4,9,.8);background-image:none;filter:none}.btn:active{background-color:#d8dde1;border-color:#2c2f34;border-color:rgba(1,4,9,.8);box-shadow:inset 0 .15em .3em rgba(1,4,9,.15)}.social-count{color:#0e1116;background-color:#fff;border-color:#34363a;border-color:rgba(1,4,9,.8)}.social-count:focus,.social-count:hover{color:#0349b4}.octicon-heart{color:#971368}",dark:".btn{color:#c9d1d9;background-color:#1a1e23;border-color:#2f3439;border-color:rgba(240,246,252,.1);background-image:url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'%3e%3clinearGradient id='o' x2='0' y2='1'%3e%3cstop stop-color='%2321262d'/%3e%3cstop offset='90%25' stop-color='%231a1e23'/%3e%3c/linearGradient%3e%3crect width='100%25' height='100%25' fill='url(%23o)'/%3e%3c/svg%3e\");background-image:-moz-linear-gradient(top, #21262d, #1a1e23 90%);background-image:linear-gradient(180deg, #21262d, #1a1e23 90%);filter:progid:DXImageTransform.Microsoft.Gradient(startColorstr='#FF21262D', endColorstr='#FF191D22')}:root .btn{filter:none}.btn:focus,.btn:hover{background-color:#292e33;background-position:0 -0.5em;border-color:#8b949e;background-image:url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'%3e%3clinearGradient id='o' x2='0' y2='1'%3e%3cstop stop-color='%2330363d'/%3e%3cstop offset='90%25' stop-color='%23292e33'/%3e%3c/linearGradient%3e%3crect width='100%25' height='100%25' fill='url(%23o)'/%3e%3c/svg%3e\");background-image:-moz-linear-gradient(top, #30363d, #292e33 90%);background-image:linear-gradient(180deg, #30363d, #292e33 90%);filter:progid:DXImageTransform.Microsoft.Gradient(startColorstr='#FF30363D', endColorstr='#FF282D32')}:root .btn:focus,:root .btn:hover{filter:none}.btn:active{background-color:#161719;border-color:#8b949e;box-shadow:inset 0 .15em .3em rgba(1,4,9,.15);background-image:none;filter:none}.social-count{color:#c9d1d9;background-color:#0d1117;border-color:#24282e;border-color:rgba(240,246,252,.1)}.social-count:focus,.social-count:hover{color:#58a6ff}.octicon-heart{color:#db61a2}",dark_dimmed:".btn{color:#adbac7;background-color:#30363d;border-color:#40464e;border-color:rgba(205,217,229,.1);background-image:url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'%3e%3clinearGradient id='o' x2='0' y2='1'%3e%3cstop stop-color='%23373e47'/%3e%3cstop offset='90%25' stop-color='%2330363d'/%3e%3c/linearGradient%3e%3crect width='100%25' height='100%25' fill='url(%23o)'/%3e%3c/svg%3e\");background-image:-moz-linear-gradient(top, #373e47, #30363d 90%);background-image:linear-gradient(180deg, #373e47, #30363d 90%);filter:progid:DXImageTransform.Microsoft.Gradient(startColorstr='#FF373E47', endColorstr='#FF2F353C')}:root .btn{filter:none}.btn:focus,.btn:hover{background-color:#3c444d;background-position:0 -0.5em;border-color:#768390;background-image:url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'%3e%3clinearGradient id='o' x2='0' y2='1'%3e%3cstop stop-color='%23444c56'/%3e%3cstop offset='90%25' stop-color='%233c444d'/%3e%3c/linearGradient%3e%3crect width='100%25' height='100%25' fill='url(%23o)'/%3e%3c/svg%3e\");background-image:-moz-linear-gradient(top, #444c56, #3c444d 90%);background-image:linear-gradient(180deg, #444c56, #3c444d 90%);filter:progid:DXImageTransform.Microsoft.Gradient(startColorstr='#FF444C56', endColorstr='#FF3B434C')}:root .btn:focus,:root .btn:hover{filter:none}.btn:active{background-color:#2e3031;border-color:#768390;box-shadow:inset 0 .15em .3em rgba(28,33,40,.15);background-image:none;filter:none}.social-count{color:#adbac7;background-color:#22272e;border-color:#333940;border-color:rgba(205,217,229,.1)}.social-count:focus,.social-count:hover{color:#539bf5}.octicon-heart{color:#c96198}",dark_high_contrast:".btn{color:#f0f3f6;background-color:#272b33;border-color:#7a828e;background-image:none;filter:none}.btn:focus,.btn:hover{background-color:#4a515b;background-position:0 -0.5em;border-color:#bdc4cc;background-image:none;filter:none}.btn:active{background-color:#1d1d1f;border-color:#bdc4cc;box-shadow:inset 0 .15em .3em rgba(1,4,9,.15)}.social-count{color:#f0f3f6;background-color:#0a0c10;border-color:#7a828e}.social-count:focus,.social-count:hover{color:#71b7ff}.octicon-heart{color:#ef6eb1}"},z=function(e,o){return"@media(prefers-color-scheme:"+e+"){"+x[f(x,o)?o:e]+"}"},y={"comment-discussion":{heights:{16:{width:16,path:'<path fill-rule="evenodd" d="M1.5 2.75a.25.25 0 01.25-.25h8.5a.25.25 0 01.25.25v5.5a.25.25 0 01-.25.25h-3.5a.75.75 0 00-.53.22L3.5 11.44V9.25a.75.75 0 00-.75-.75h-1a.25.25 0 01-.25-.25v-5.5zM1.75 1A1.75 1.75 0 000 2.75v5.5C0 9.216.784 10 1.75 10H2v1.543a1.457 1.457 0 002.487 1.03L7.061 10h3.189A1.75 1.75 0 0012 8.25v-5.5A1.75 1.75 0 0010.25 1h-8.5zM14.5 4.75a.25.25 0 00-.25-.25h-.5a.75.75 0 110-1.5h.5c.966 0 1.75.784 1.75 1.75v5.5A1.75 1.75 0 0114.25 12H14v1.543a1.457 1.457 0 01-2.487 1.03L9.22 12.28a.75.75 0 111.06-1.06l2.22 2.22v-2.19a.75.75 0 01.75-.75h1a.25.25 0 00.25-.25v-5.5z"></path>'}}},download:{heights:{16:{width:16,path:'<path fill-rule="evenodd" d="M7.47 10.78a.75.75 0 001.06 0l3.75-3.75a.75.75 0 00-1.06-1.06L8.75 8.44V1.75a.75.75 0 00-1.5 0v6.69L4.78 5.97a.75.75 0 00-1.06 1.06l3.75 3.75zM3.75 13a.75.75 0 000 1.5h8.5a.75.75 0 000-1.5h-8.5z"></path>'}}},eye:{heights:{16:{width:16,path:'<path fill-rule="evenodd" d="M1.679 7.932c.412-.621 1.242-1.75 2.366-2.717C5.175 4.242 6.527 3.5 8 3.5c1.473 0 2.824.742 3.955 1.715 1.124.967 1.954 2.096 2.366 2.717a.119.119 0 010 .136c-.412.621-1.242 1.75-2.366 2.717C10.825 11.758 9.473 12.5 8 12.5c-1.473 0-2.824-.742-3.955-1.715C2.92 9.818 2.09 8.69 1.679 8.068a.119.119 0 010-.136zM8 2c-1.981 0-3.67.992-4.933 2.078C1.797 5.169.88 6.423.43 7.1a1.619 1.619 0 000 1.798c.45.678 1.367 1.932 2.637 3.024C4.329 13.008 6.019 14 8 14c1.981 0 3.67-.992 4.933-2.078 1.27-1.091 2.187-2.345 2.637-3.023a1.619 1.619 0 000-1.798c-.45-.678-1.367-1.932-2.637-3.023C11.671 2.992 9.981 2 8 2zm0 8a2 2 0 100-4 2 2 0 000 4z"></path>'}}},heart:{heights:{16:{width:16,path:'<path fill-rule="evenodd" d="M4.25 2.5c-1.336 0-2.75 1.164-2.75 3 0 2.15 1.58 4.144 3.365 5.682A20.565 20.565 0 008 13.393a20.561 20.561 0 003.135-2.211C12.92 9.644 14.5 7.65 14.5 5.5c0-1.836-1.414-3-2.75-3-1.373 0-2.609.986-3.029 2.456a.75.75 0 01-1.442 0C6.859 3.486 5.623 2.5 4.25 2.5zM8 14.25l-.345.666-.002-.001-.006-.003-.018-.01a7.643 7.643 0 01-.31-.17 22.075 22.075 0 01-3.434-2.414C2.045 10.731 0 8.35 0 5.5 0 2.836 2.086 1 4.25 1 5.797 1 7.153 1.802 8 3.02 8.847 1.802 10.203 1 11.75 1 13.914 1 16 2.836 16 5.5c0 2.85-2.045 5.231-3.885 6.818a22.08 22.08 0 01-3.744 2.584l-.018.01-.006.003h-.002L8 14.25zm0 0l.345.666a.752.752 0 01-.69 0L8 14.25z"></path>'}}},"issue-opened":{heights:{16:{width:16,path:'<path d="M8 9.5a1.5 1.5 0 100-3 1.5 1.5 0 000 3z"></path><path fill-rule="evenodd" d="M8 0a8 8 0 100 16A8 8 0 008 0zM1.5 8a6.5 6.5 0 1113 0 6.5 6.5 0 01-13 0z"></path>'}}},"mark-github":{heights:{16:{width:16,path:'<path fill-rule="evenodd" d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0016 8c0-4.42-3.58-8-8-8z"></path>'}}},package:{heights:{16:{width:16,path:'<path fill-rule="evenodd" d="M8.878.392a1.75 1.75 0 00-1.756 0l-5.25 3.045A1.75 1.75 0 001 4.951v6.098c0 .624.332 1.2.872 1.514l5.25 3.045a1.75 1.75 0 001.756 0l5.25-3.045c.54-.313.872-.89.872-1.514V4.951c0-.624-.332-1.2-.872-1.514L8.878.392zM7.875 1.69a.25.25 0 01.25 0l4.63 2.685L8 7.133 3.245 4.375l4.63-2.685zM2.5 5.677v5.372c0 .09.047.171.125.216l4.625 2.683V8.432L2.5 5.677zm6.25 8.271l4.625-2.683a.25.25 0 00.125-.216V5.677L8.75 8.432v5.516z"></path>'}}},play:{heights:{16:{width:16,path:'<path fill-rule="evenodd" d="M1.5 8a6.5 6.5 0 1113 0 6.5 6.5 0 01-13 0zM8 0a8 8 0 100 16A8 8 0 008 0zM6.379 5.227A.25.25 0 006 5.442v5.117a.25.25 0 00.379.214l4.264-2.559a.25.25 0 000-.428L6.379 5.227z"></path>'}}},"repo-forked":{heights:{16:{width:16,path:'<path fill-rule="evenodd" d="M5 3.25a.75.75 0 11-1.5 0 .75.75 0 011.5 0zm0 2.122a2.25 2.25 0 10-1.5 0v.878A2.25 2.25 0 005.75 8.5h1.5v2.128a2.251 2.251 0 101.5 0V8.5h1.5a2.25 2.25 0 002.25-2.25v-.878a2.25 2.25 0 10-1.5 0v.878a.75.75 0 01-.75.75h-4.5A.75.75 0 015 6.25v-.878zm3.75 7.378a.75.75 0 11-1.5 0 .75.75 0 011.5 0zm3-8.75a.75.75 0 100-1.5.75.75 0 000 1.5z"></path>'}}},"repo-template":{heights:{16:{width:16,path:'<path fill-rule="evenodd" d="M6 .75A.75.75 0 016.75 0h2.5a.75.75 0 010 1.5h-2.5A.75.75 0 016 .75zm5 0a.75.75 0 01.75-.75h1.5a.75.75 0 01.75.75v1.5a.75.75 0 01-1.5 0V1.5h-.75A.75.75 0 0111 .75zM4.992.662a.75.75 0 01-.636.848c-.436.063-.783.41-.846.846a.75.75 0 01-1.485-.212A2.501 2.501 0 014.144.025a.75.75 0 01.848.637zM2.75 4a.75.75 0 01.75.75v1.5a.75.75 0 01-1.5 0v-1.5A.75.75 0 012.75 4zm10.5 0a.75.75 0 01.75.75v1.5a.75.75 0 01-1.5 0v-1.5a.75.75 0 01.75-.75zM2.75 8a.75.75 0 01.75.75v.268A1.72 1.72 0 013.75 9h.5a.75.75 0 010 1.5h-.5a.25.25 0 00-.25.25v.75c0 .28.114.532.3.714a.75.75 0 01-1.05 1.072A2.495 2.495 0 012 11.5V8.75A.75.75 0 012.75 8zm10.5 0a.75.75 0 01.75.75v4.5a.75.75 0 01-.75.75h-2.5a.75.75 0 010-1.5h1.75v-2h-.75a.75.75 0 010-1.5h.75v-.25a.75.75 0 01.75-.75zM6 9.75A.75.75 0 016.75 9h2.5a.75.75 0 010 1.5h-2.5A.75.75 0 016 9.75zm-1 2.5v3.25a.25.25 0 00.4.2l1.45-1.087a.25.25 0 01.3 0L8.6 15.7a.25.25 0 00.4-.2v-3.25a.25.25 0 00-.25-.25h-3.5a.25.25 0 00-.25.25z"></path>'}}},star:{heights:{16:{width:16,path:'<path fill-rule="evenodd" d="M8 .25a.75.75 0 01.673.418l1.882 3.815 4.21.612a.75.75 0 01.416 1.279l-3.046 2.97.719 4.192a.75.75 0 01-1.088.791L8 12.347l-3.766 1.98a.75.75 0 01-1.088-.79l.72-4.194L.818 6.374a.75.75 0 01.416-1.28l4.21-.611L7.327.668A.75.75 0 018 .25zm0 2.445L6.615 5.5a.75.75 0 01-.564.41l-3.097.45 2.24 2.184a.75.75 0 01.216.664l-.528 3.084 2.769-1.456a.75.75 0 01.698 0l2.77 1.456-.53-3.084a.75.75 0 01.216-.664l2.24-2.183-3.096-.45a.75.75 0 01-.564-.41L8 2.694v.001z"></path>'}}}},C=function(e,o){e=b(e).replace(/^octicon-/,""),f(y,e)||(e="mark-github");var t=o>=24&&24 in y[e].heights?24:16,r=y[e].heights[t];return'<svg viewBox="0 0 '+r.width+" "+t+'" width="'+o*r.width/t+'" height="'+o+'" class="octicon octicon-'+e+'" aria-hidden="true">'+r.path+"</svg>"},M={},A=function(e,o){var t=M[e]||(M[e]=[]);if(!(t.push(o)>1)){var r=g((function(){for(delete M[e];o=t.shift();)o.apply(null,arguments)}));if(l){var n=new a;m(n,"abort",r),m(n,"error",r),m(n,"load",(function(){var e;try{e=JSON.parse(this.responseText)}catch(e){return void r(e)}r(200!==this.status,e)})),n.open("GET",e),n.send()}else{var i=this||window;i._=function(e){i._=null,r(200!==e.meta.status,e.data)};var c=u(i.document)("script",{async:!0,src:e+(-1!==e.indexOf("?")?"&":"?")+"callback=_"}),d=function(){i._&&i._({meta:{}})};m(c,"load",d),m(c,"error",d),k(c,/de|m/,d),i.document.getElementsByTagName("head")[0].appendChild(c)}}},F=function(e,o,t){var r=u(e.ownerDocument),a=e.appendChild(r("style",{type:"text/css"})),n="body{margin:0}a{text-decoration:none;outline:0}.widget{display:inline-block;overflow:hidden;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif;font-size:0;line-height:0;white-space:nowrap}.btn,.social-count{position:relative;display:inline-block;display:inline-flex;height:14px;padding:2px 5px;font-size:11px;font-weight:600;line-height:14px;vertical-align:bottom;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-repeat:repeat-x;background-position:-1px -1px;background-size:110% 110%;border:1px solid}.btn{border-radius:.25em}.btn:not(:last-child){border-radius:.25em 0 0 .25em}.social-count{border-left:0;border-radius:0 .25em .25em 0}.widget-lg .btn,.widget-lg .social-count{height:16px;padding:5px 10px;font-size:12px;line-height:16px}.octicon{display:inline-block;vertical-align:text-top;fill:currentColor;overflow:visible}"+function(e){if(null==e)return x.light;if(f(x,e))return x[e];var o=p(e,";",":",(function(e){return e.replace(/^[ \t\n\f\r]+|[ \t\n\f\r]+$/g,"")}));return x[f(x,o["no-preference"])?o["no-preference"]:"light"]+z("light",o.light)+z("dark",o.dark)}(o["data-color-scheme"]);a.styleSheet?a.styleSheet.cssText=n:a.appendChild(e.ownerDocument.createTextNode(n));var i="large"===b(o["data-size"]),l=r("a",{className:"btn",href:o.href,rel:"noopener",target:"_blank",title:o.title||void 0,"aria-label":o["aria-label"]||void 0,innerHTML:C(o["data-icon"],i?16:14)+"&nbsp;"},[r("span",{},[o["data-text"]||""])]),d=e.appendChild(r("div",{className:"widget"+(i?" widget-lg":"")},[l])),s=l.hostname.replace(/\.$/,"");if(("."+s).substring(s.length-c.length)!=="."+c)return l.removeAttribute("href"),void t(d);var h=(" /"+l.pathname).split(/\/+/);if(((s===c||s==="gist."+c)&&"archive"===h[3]||s===c&&"releases"===h[3]&&("download"===h[4]||"latest"===h[4]&&"download"===h[5])||s==="codeload."+c)&&(l.target="_top"),"true"===b(o["data-show-count"])&&s===c&&"marketplace"!==h[1]&&"sponsors"!==h[1]&&"orgs"!==h[1]&&"users"!==h[1]&&"-"!==h[1]){var g,m;if(!h[2]&&h[1])m="followers",g="?tab=followers";else if(!h[3]&&h[2])m="stargazers_count",g="/stargazers";else if(h[4]||"subscription"!==h[3])if(h[4]||"fork"!==h[3]){if("issues"!==h[3])return void t(d);m="open_issues_count",g="/issues"}else m="forks_count",g="/network/members";else m="subscribers_count",g="/watchers";var v=h[2]?"/repos/"+h[1]+"/"+h[2]:"/users/"+h[1];A.call(this,"https://api.github.com"+v,(function(e,o){if(!e){var a=o[m];d.appendChild(r("a",{className:"social-count",href:o.html_url+g,rel:"noopener",target:"_blank","aria-label":a+" "+m.replace(/_count$/,"").replace("_"," ").slice(0,a<2?-1:void 0)+" on GitHub"},[(""+a).replace(/\B(?=(\d{3})+(?!\d))/g,",")]))}t(d)}))}else t(d)},L=window.devicePixelRatio||1,_=function(e){return(L>1?t.ceil(t.round(e*L)/L*2)/2:t.ceil(e))||0},E=function(e,o){e.style.width=o[0]+"px",e.style.height=o[1]+"px"},G=function(o,r){if(null!=o&&null!=r)if(o.getAttribute&&(o=function(e){var o={href:e.href,title:e.title,"aria-label":e.getAttribute("aria-label")};return s(["icon","color-scheme","text","size","show-count"],(function(t){var r="data-"+t;o[r]=e.getAttribute(r)})),null==o["data-text"]&&(o["data-text"]=e.textContent||e.innerText),o}(o)),d){var a=h("span");F(a.attachShadow({mode:"closed"}),o,(function(){r(a)}))}else{var n=h("iframe",{src:"javascript:0",title:o.title||void 0,allowtransparency:!0,scrolling:"no",frameBorder:0});E(n,[0,0]),n.style.border="none";var c=function(){var a,l=n.contentWindow;try{a=l.document.body}catch(o){return void e.body.appendChild(n.parentNode.removeChild(n))}v(n,"load",c),F.call(l,a,o,(function(e){var a=function(e){var o=e.offsetWidth,r=e.offsetHeight;if(e.getBoundingClientRect){var a=e.getBoundingClientRect();o=t.max(o,_(a.width)),r=t.max(r,_(a.height))}return[o,r]}(e);n.parentNode.removeChild(n),w(n,"load",(function(){E(n,a)})),n.src=i+"#"+(n.name=function(e,o,t,r){null==o&&(o="&"),null==t&&(t="="),null==r&&(r=window.encodeURIComponent);var a=[];for(var n in e){var i=e[n];null!=i&&a.push(r(n)+t+r(i))}return a.join(o)}(o)),r(n)}))};m(n,"load",c),e.body.appendChild(n)}};o.protocol+"//"+o.host+o.pathname===i?F(e.body,p(window.name||o.hash.replace(/^#/,"")),(function(){})):function(o){if("complete"===e.readyState||"loading"!==e.readyState&&!e.documentElement.doScroll)setTimeout(o);else if(e.addEventListener){var t=g(o);w(e,"DOMContentLoaded",t),w(window,"load",t)}else k(e,/m/,o)}((function(){var o,t=e.querySelectorAll?e.querySelectorAll("a."+n):(o=[],s(e.getElementsByTagName("a"),(function(e){-1!==(" "+e.className+" ").replace(/[ \t\n\f\r]+/g," ").indexOf(" github-button ")&&o.push(e)})),o);s(t,(function(e){G(e,(function(o){e.parentNode.replaceChild(o,e)}))}))}))}();
        </script>
        <!-- Place this tag where you want the button to render. -->
        <a class="github-button" href="https://github.com/wenlng/go-captcha" data-size="large"
           data-show-count="true" aria-label="Star wenlng/go-captcha on GitHub">Star</a>
        <!-- Place this tag where you want the button to render. -->
        <a class="github-button" href="https://github.com/wenlng/go-captcha/fork" data-size="large"
           data-show-count="true" aria-label="Fork wenlng/go-captcha on GitHub">Fork</a>
    </div>
</div>
</body>

<script type="text/javascript">

    /** =================================================================================
     Github：https://github.com/wenlng/go-captcha
     Go实例代码：https://github.com/wenlng/go-captcha-example
     Vue实例代码：https://github.com/wenlng/go-captcha-vue
     React实例代码：https://github.com/wenlng/go-captcha-react
     在线演示：http://47.104.180.148:8081/go_captcha_demo
     * ==================================================================================
     */

    /**
     * @Description:  封装Ajax
     * @return post Function
     get Function
     */
    const Ajax = (function () {
        var xhr
        var requestArr = []

        /**
         * @Description: 初始化
         */
        function __initialize() {
            if(window.XMLHttpRequest){
                xhr = new XMLHttpRequest()
            } else if(window.ActiveObject){
                xhr = new ActiveXobject('Microsoft.XMLHTTP')
            }
        }

        /**
         * @Description: 请求处理
         * @param options
         */
        function requestHandler(options){
            options = options || {}
            // 请求格式GET、POST，默认为GET
            options.type = (options.type || "GET").toUpperCase()
            // 响应数据格式，默认json
            options.dataType = options.dataType || "json"
            // options.data请求的数据
            const params = ajaxFormatParams(options.data)

            // 启动并发送一个请求
            if(options.type === "GET"){
                xhr.open("GET", options.url+"?" + params,true);
                xhr.send(null);
            }else if(options.type === "POST"){
                xhr.open("post",options.url,true);
                // 设置表单提交时的内容类型
                xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
                xhr.send(params);
            }

            xhr.timeout = options.timeout

            // 设置有效时间
            setTimeout(function(){
                if(xhr.readySate !== 4){
                    xhr.abort();
                }
            }, options.timeout)

            // onreadystatechange
            xhr.onreadystatechange = function(){
                if(xhr.readyState === 4){
                    var status = xhr.status;
                    if(status >= 200 && status < 300 || status === 304){
                        var data = xhr.responseText
                        if (isJSONString(data)) {
                            data = eval("("+xhr.responseText+")")
                        }
                        options.success&&options.success(data, xhr.responseXML);
                    }else{
                        options.error&&options.error(status);
                    }
                }
                options.complete&&options.complete(status);
            }
        }

        /**
         * @Description: 是否是Json格式
         * @param str
         */
        function isJSONString(str) {
            if (typeof str == 'string') {
                try {
                    var obj = JSON.parse(str)
                    return typeof obj == 'object' && obj
                } catch(e) {}
            }

            return false
        }

        /**
         * @Description: Ajax格式化请求参数
         * @param data
         */
        function ajaxFormatParams(data){
            var arr = [];
            for(var name in data){
                arr.push(encodeURIComponent(name) + "=" + encodeURIComponent(data[name]))
            }
            arr.push(("v=" + Math.random()).replace(".",""))
            return arr.join("&")
        }

        /**
         * @Description: 处理Post请求
         * @param url
         * @param data
         * @param success
         * @param error
         * @param complete
         */
        function handlePost (url, data, success, error, complete) {
            requestHandler({
                url: url,
                type: 'POST',
                data: data,
                dataType:'json',
                timeout: 10000,
                contentType: "application/json",
                success: success,
                error: error,
                complete: complete
            })
        }

        /**
         * @Description: 处理Get请求
         * @param url
         * @param data
         * @param success
         * @param error
         * @param complete
         */
        function handleGet (url, data, success, error, complete) {
            requestHandler({
                url: url,
                type: 'GET',
                data: data,
                dataType:'json',
                timeout: 10000,
                success: success,
                error: error,
                complete: complete
            })
        }

        __initialize()
        return {
            post: handlePost,
            get: handleGet
        }
    })();

    /**
     * @Description: 封装Captcha
     */
    const Captcha = (function () {
        /**
         * @Description: 唯一KEY值，用作验证使用
         */
        var captchaKey = ""
        /**
         * @Description: 用户鼠标点击的位置 x,y
         */
        var dots = []
        /**
         * @Description: 最大可点数
         */
        var maxDot = 8

        const captchaWrapDom        = document.querySelector("#wg-cap-dots")
        const captchaImageDom       = document.querySelector("#wg-cap-image")
        const captchaThumbDom       = document.querySelector("#wg-cap-thumb")
        const captchaBtnControlDom  = document.querySelector("#wg-cap-btn-control")
        const captchaCheckBtnDom    = document.querySelector("#wg-cap-check-btn")
        const captchaCloseBtnDom    = document.querySelector("#wg-cap-close-btn")
        const captchaDialogBtnDom   = document.querySelector("#wg-cap-dialog")
        const captchaRefreshBtnDom  = document.querySelector("#wg-cap-refresh-btn")
        const captchaDefaultBtnDom  = document.querySelector("#wg-cap-btn-default")
        const captchaErrorBtnDom    = document.querySelector("#wg-cap-btn-error")
        const captchaOverBtnDom     = document.querySelector("#wg-cap-btn-over")
        const dialogDom             = document.querySelector("#wg-cap-container")

        /**
         * @Description: 初始化
         */
        function __initialize() {
            requestCaptchaData()
            handleEvent()

            // 禁用移动端缩放
            document.addEventListener('touchstart', (event) => {
                if (event.touches.length > 1) {
                    event.preventDefault()
                }
            })
            document.addEventListener('gesturestart', (event) => {
                event.preventDefault()
            })
            // touchstart  解决:hover伪类在移动端二次点击的问题
            document.body.addEventListener('touchend', () => { })
        }

        /**
         * @Description: 处理所有事件
         */
        function handleEvent() {
            addEventListener(captchaImageDom, "click", handleClickPos)
            addEventListener(captchaCheckBtnDom, "click", handleClickCheck)
            addEventListener(captchaCloseBtnDom, "click", handleClickClose)
            addEventListener(captchaDialogBtnDom, "click", handleClickClose)
            addEventListener(captchaRefreshBtnDom, "click", handleClickRefresh)
            addEventListener(captchaDefaultBtnDom, "click", handleClickDefault)
            addEventListener(captchaErrorBtnDom, "click", handleClickDefault)
            addEventListener(captchaOverBtnDom, "click", handleClickDefault)
        }

        /**
         * @Description: 为任意元素.绑定任意的事件
         * @param el    任意的元素
         * @param type  事件的类型
         * @param fn    事件处理函数
         */
        function addEventListener(el,type,fn) {
            //判断浏览器是否支持这个方法
            if(el.addEventListener){
                el.addEventListener(type,fn,false);
            }else if(el.attachEvent){
                el.attachEvent("on" + type,fn);
            }else{
                el["on" + type]=fn;
            }
        }

        /**
         * @Description: 找到元素的屏幕位置
         * @param el
         */
        function calcLocationLeft(el){
            var tmp = el.offsetLeft
            var val = el.offsetParent
            while(val != null){
                tmp += val.offsetLeft
                val = val.offsetParent
            }
            return tmp
        }

        /**
         * @Description: 找到元素的屏幕位置
         * @param el
         */
        function calcLocationTop(el){
            var tmp = el.offsetTop
            var val = el.offsetParent
            while(val != null){
                tmp += val.offsetTop
                val = val.offsetParent
            }
            return tmp
        }

        /**
         * @Description: 找到元素的屏幕位置
         * @param dom
         */
        function getDomXY(dom){
            var x = 0
            var y = 0
            if (dom.getBoundingClientRect) {
                var box = dom.getBoundingClientRect();
                var D = document.documentElement;
                x = box.left + Math.max(D.scrollLeft, document.body.scrollLeft) - D.clientLeft;
                y = box.top + Math.max(D.scrollTop, document.body.scrollTop) - D.clientTop
            }
            else{
                while (dom !== document.body) {
                    x += dom.offsetLeft
                    y += dom.offsetTop
                    dom = dom.offsetParent
                }
            }
            return {
                domX: x,
                domY: y
            }
        }

        /**
         * @Description: 插入点击icon大小为22x22
         * @param event
         * @param x
         * @param y
         */
        function appendDotIcon(event, x, y) {
            // const icon = '<div class="wg-cap-wrap__dot" style="position:absolute; top:' + (y * 0.5) + 'px; left:' + (x * 0.5) + 'px;"><span>'+ (dots.length + 1) +'</span></div>'
            const dot = document.createElement('div')
            dot.setAttribute('class', 'wg-cap-wrap__dot')
            dot.setAttribute('style', 'top:' + (y - 11) + 'px; left:' + (x - 11) + 'px;')
            dot.innerHTML = '<span>'+ (dots.length + 1) +'</span>'
            captchaWrapDom.appendChild(dot)

            dots.push([x, y])
        }

        /**
         * @Description: 重置
         */
        function resetCaptcha() {
            captchaKey = ""
            dots = []
            captchaWrapDom.innerHTML = ""
        }

        /**
         * @Description: 清空验证图片
         */
        function clearImage() {
            captchaImageDom.setAttribute("src", "")
            captchaThumbDom.setAttribute("src", "")
        }

        /**
         * @Description: 处理点击验证码图片位置
         * @param ev
         */
        function handleClickPos(ev){
            if (dots.length >= maxDot || captchaKey === "") {
                return
            }

            const e = ev || window.event;
            e.preventDefault()
            const dom = e.currentTarget

            const xy = getDomXY(dom)
            const domX = xy.domX
            const domY = xy.domY
            // ===============================================
            // @notice 如 getDomXY 不准确可尝试使用 calcLocationLeft 或 calcLocationTop
            // const domX = this.calcLocationLeft(dom)
            // const domY = this.calcLocationTop(dom)
            // ===============================================

            const mouseX = (navigator.appName === 'Netscape') ? e.pageX : e.x + document.body.scrollLeft
            const mouseY = (navigator.appName === 'Netscape') ? e.pageY : e.y+document.body.scrollTop

            // 计算点击的相对位置
            const xPos = mouseX - domX;
            const yPos = mouseY - domY;

            appendDotIcon(e, parseInt(xPos.toString()), parseInt(yPos.toString()))
            // appendDotIcon(e, xPos, yPos)
            e.cancelBubble = true
            e.preventDefault()
            return false
        }

        /**
         * @Description: 点击刷新
         */
        function handleClickRefresh() {
            requestCaptchaData()
        }

        /**
         * @Description: 点击刷新
         */
        function handleClickClose() {
            dialogDom.classList.remove("wg-cap-dialog__active")
        }

        /**
         * @Description: 点击验证
         */
        function handleClickCheck() {
            var dotsA = []
            dots.forEach(function (value, key) {
                dotsA.push(value.join(","))
            })

            if (dotsA.length <= 0) {
                alert("请点选图案进行验证")
                return
            }

            requestCheckCaptchaData({'dots': dotsA.join(','), 'key': captchaKey})
        }

        /**
         * @Description: 点击验证按钮，弹窗
         */
        function handleClickDefault() {
            requestCaptchaData()
            dialogDom.classList.add("wg-cap-dialog__active")
        }

        /**
         * @Description: 请求验证码数据
         */
        function requestCaptchaData() {
            resetCaptcha()
            clearImage()
            captchaImageDom.classList.add("wg-cap-wrap__hidden")
            captchaThumbDom.classList.add("wg-cap-wrap__hidden")

            Ajax.get("/api/go_captcha_data", {}, function(data){
                if (data['code'] === 0) {
                    captchaImageDom.classList.remove("wg-cap-wrap__hidden")
                    captchaThumbDom.classList.remove("wg-cap-wrap__hidden")
                    captchaImageDom.setAttribute("src", data['image_base64'])
                    captchaThumbDom.setAttribute("src", data['thumb_base64'])
                    captchaKey = data['captcha_key']
                } else {
                    alert("请求验证码数据失败：" + data['message'])
                }
            }, function(e){
                console.log("请求验证码数据失败：" + e['message']);
            })
        }

        /**
         * @Description: 请求验证数据
         * @param dots
         */
        function requestCheckCaptchaData(dots) {
            Ajax.post("/api/go_captcha_check_data", dots, function(data){
                captchaBtnControlDom.classList.remove("wg-cap-active__default")
                captchaBtnControlDom.classList.remove("wg-cap-active__over")
                if (data['code'] === 0) {
                    alert("验证成功")
                    captchaBtnControlDom.classList.remove("wg-cap-active__error")
                    captchaBtnControlDom.classList.add("wg-cap-active__success")
                    setTimeout(function () {
                        handleClickClose()
                    }, 200)
                } else {
                    alert("验证失败")
                    captchaBtnControlDom.classList.remove("wg-cap-active__success")
                    captchaBtnControlDom.classList.add("wg-cap-active__error")
                }
            }, function(e){
                captchaBtnControlDom.classList.remove("wg-cap-active__default")
                captchaBtnControlDom.classList.remove("wg-cap-active__over")
                captchaBtnControlDom.classList.remove("wg-cap-active__success")
                captchaBtnControlDom.classList.add("wg-cap-active__error")
            }, function () {
                captchaKey = ""
            })
        }

        __initialize()
        return {}
    })();
</script>
</html>
